﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataAccessLayer;
using EntityDataModel;
using CommonUtils;

namespace BusinessLogicLayer
{
    public class MessageBLL
    {
        #region businesslogic

        /// <summary>     
        /// Create a status message for a given username
        /// </summary>
        public static void SendPublicMessage(String senderName, String receiverName, String messageContent)
        {
            try
            {
                if (IsALink(messageContent))
                {
                    messageContent = ShortenLink(messageContent);
                }
                MessageDAL.SendPublicMessage(senderName.Trim(), receiverName.Trim(), messageContent.TrimEnd());
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        /// <summary>     
        /// Send a message from a given user to a given user 
        /// </summary>
        public static void SendPrivateMessage(String senderName, String receiverName, String messageContent)
        {
            try
            {
                if (IsALink(messageContent))
                {
                    messageContent = ShortenLink(messageContent);
                }
                MessageDAL.SendPrivateMessage(senderName.Trim(), receiverName.Trim(), messageContent.TrimEnd());
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        /// <summary>     
        /// Add a comment to the given message
        /// </summary>
        public static void AddComment(String senderName, String messageId, String messageContent)
        {
            try
            {
                if (IsALink(messageContent))
                {
                    messageContent = ShortenLink(messageContent);
                }
                MessageDAL.AddComment(senderName.Trim(), MessageDAL.GetMessageById(messageId), messageContent.Trim());
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        /// <summary>     
        /// Add a "like" to the given message 
        /// </summary>
        public static void LikeMessage(String userName, String messageId)
        {
            try
            {
                if(!MessageDAL.IsUserAlreadyLikingMessage(UserDAL.GetUserByUserName(userName), MessageDAL.GetMessageById(messageId))) {
                    MessageDAL.LikeMessage(UserDAL.GetUserByUserName(userName), MessageDAL.GetMessageById(messageId));
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        /// <summary>     
        /// Add a "like" to the given message 
        /// </summary>
        public static void LikeComment(String userName, String commentId)
        {
            try
            {
                if (!MessageDAL.IsUserAlreadyLikingComment(UserDAL.GetUserByUserName(userName), MessageDAL.GetCommentById(commentId)))
                {
                    MessageDAL.LikeComment(UserDAL.GetUserByUserName(userName), MessageDAL.GetCommentById(commentId));
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        /// <summary>     
        /// Get all comments for the given message 
        /// </summary>
        public static List<Comment> GetAllCommentsForMessage(String messageID)
        {
            try
            {
                List<Comment> comments = MessageDAL.GetAllCommentsForMessage(messageID);
                foreach (Comment comment in comments)
                {
                    if (MessageBLL.IsALink(comment.CommentContent))
                    {
                        comment.CommentContent = MessageBLL.TransformToHtmlLink(comment.CommentContent);
                    }
                }
                return comments;
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        /// <summary>     
        /// Get all messages where the username in parameter is the receiver.
        /// </summary>
        public static List<Message> GetAllPrivateMessagesForUser(String userName)
        {
            try
            {
                List<Message> messages = MessageDAL.GetAllPrivateMessagesForUser(userName.Trim());
                foreach (Message message in messages)
                {
                    if (MessageBLL.IsALink(message.MessageContent))
                    {
                        message.MessageContent = MessageBLL.TransformToHtmlLink(message.MessageContent);
                    }
                }
                return messages;
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        /// <summary>
        /// Check if the user already likes the given message
        /// </summary>
        public static Boolean IsUserAlreadyLikingMessage(String userName, String messageID)
        {
            using (liveCPEEntities context = new liveCPEEntities())
            {
                try
                {
                    return MessageDAL.IsUserAlreadyLikingMessage(UserDAL.GetUserByUserName(userName), MessageDAL.GetMessageById(messageID));
                }
                catch (Exception e)
                {
                    System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                    LogDAL.AddLog(e.Message, "Error", BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name, DateTime.Now);
                    throw new Exception(sf.GetMethod().Name + " unexpected error", e);
                }
            }
        }

        #endregion

        #region tools
        /// <summary>     
        /// Shorten a url given in parameter with the bit.ly API
        /// </summary>
        private static String ShortenLink(string messageContent)
        {
            try
            {
                String[] words = messageContent.Split(' ');
                String sentence = "";
                for (int i = 0; i < words.Length; i++)
                {
                    if (IsALink(words[i]))
                    {
                        var url = BitLyAPI.ShortenUrl(words[i]).ShortUrl;
                        words[i] = url;
                    }
                    if (i == words.Length - 1)
                    {
                        sentence += words[i];
                    }
                    else
                    {
                        sentence += words[i] + " ";
                    }
                }
                return sentence;
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        /// <summary>     
        /// Check if the given string contains an http or https link
        /// </summary>
        public static Boolean IsALink(String message)
        {
            try
            {
                if (message.Contains("http://") || message.Contains("https://"))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        /// <summary>     
        /// Transform the given message into a HTML link
        /// </summary>
        public static String TransformToHtmlLink(String message)
        {
            try
            {
                String[] words = message.Split(' ');
                String sentence = "";
                for (int i = 0; i < words.Length; i++)
                {
                    if (IsALink(words[i]))
                    {
                        words[i] = "<a href=" + words[i] + ">" + words[i] + "</a>";
                    }
                    if (i == words.Length - 1)
                    {
                        sentence += words[i];
                    }
                    else
                    {
                        sentence += words[i] + " ";
                    }
                }
                return sentence;
            }
            catch (Exception e)
            {
                System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame();
                LogWriter.AddLog(e, LogStatus.Error, BusinessLogicLayerSettings.Default.ApplicationName, sf.GetMethod().Name);
                throw new Exception(sf.GetMethod().Name + " unexpected error", e);
            }
        }

        #endregion
    }
}
